/*-------------------------------------------------------------------------
 *
 * detoast.h
 *	  访问压缩和外部 varlena 值
 *
 * Copyright (c) 2000-2022, PostgreSQL Global Development Group
 *
 * src/include/access/detoast.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef DETOAST_H
#define DETOAST_H

/*
 * 宏来获取可能未对齐的 EXTERNAL 数据内容
 * 到本地 "struct varatt_external" toast 指针。这应该是
 * 只是一个 memcpy，但某些版本的 gcc 似乎会产生假代码
 * 假设数据内容是对齐的。引入一个显式的
 * 中间 "varattrib_1b_e *" 变量似乎可以修复它。
 */
#define VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr) \
do { \
	varattrib_1b_e *attre = (varattrib_1b_e *) (attr); \
	Assert(VARATT_IS_EXTERNAL(attre)); \
	Assert(VARSIZE_EXTERNAL(attre) == sizeof(toast_pointer) + VARHDRSZ_EXTERNAL); \
	memcpy(&(toast_pointer), VARDATA_EXTERNAL(attre), sizeof(toast_pointer)); \
} while (0)

/* 包含标准 TOAST 指针的 EXTERNAL 数据的大小 */
#define TOAST_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_external))

/* 包含间接指针的 EXTERNAL 数据的大小 */
#define INDIRECT_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_indirect))

/* ----------
 * detoast_external_attr() -
 *
 *		从 toast 关系中获取外部存储属性。不会解压，
 *		如果以压缩格式存储外部数据。
 * ----------
 */
extern struct varlena *detoast_external_attr(struct varlena *attr);

/* ----------
 * detoast_attr() -
 *
 *		完全解冻一个属性，根据需要获取和/或解压
 * ----------
 */
extern struct varlena *detoast_attr(struct varlena *attr);

/* ----------
 * detoast_attr_slice() -
 *
 *		仅获取属性的指定部分。
 *		（处理所有属性存储情况）
 * ----------
 */
extern struct varlena *detoast_attr_slice(struct varlena *attr,
										  int32 sliceoffset,
										  int32 slicelength);

/* ----------
 * toast_raw_datum_size -
 *
 *		返回一个 varlena 数据的原始（解冻）大小
 * ----------
 */
extern Size toast_raw_datum_size(Datum value);

/* ----------
 * toast_datum_size -
 *
 *		返回一个 varlena 数据的存储大小
 * ----------
 */
extern Size toast_datum_size(Datum value);

#endif							/* DETOAST_H */
